package com.zenithmind.version.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zenithmind.version.pojo.domain.Tag;
import com.zenithmind.version.pojo.vo.TagVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

/**
 * 标签Mapper接口
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Mapper
public interface TagMapper extends BaseMapper<Tag> {

    /**
     * 分页查询标签（包含关联信息）
     * 
     * @param page 分页参数
     * @param repositoryId 仓库ID
     * @param tagType 标签类型
     * @param creatorId 创建者ID
     * @return 分页结果
     */
    IPage<TagVO> selectTagPageWithDetails(Page<TagVO> page,
                                         @Param("repositoryId") String repositoryId,
                                         @Param("tagType") Integer tagType,
                                         @Param("creatorId") String creatorId);

    /**
     * 获取仓库标签列表
     * 
     * @param repositoryId 仓库ID
     * @param tagType 标签类型
     * @param limit 限制数量
     * @return 标签列表
     */
    @Select("SELECT t.*, u.real_name as creator_name, c.message as commit_message " +
            "FROM tag t " +
            "LEFT JOIN user u ON t.creator_id = u.id " +
            "LEFT JOIN commit c ON t.commit_id = c.id " +
            "WHERE t.repository_id = #{repositoryId} " +
            "AND (#{tagType} IS NULL OR t.tag_type = #{tagType}) " +
            "AND t.deleted = 0 " +
            "ORDER BY t.create_time DESC " +
            "LIMIT #{limit}")
    List<TagVO> selectRepositoryTags(@Param("repositoryId") String repositoryId,
                                    @Param("tagType") Integer tagType,
                                    @Param("limit") Integer limit);

    /**
     * 获取标签详情
     * 
     * @param id 标签ID
     * @return 标签详情
     */
    TagVO selectTagDetail(@Param("id") String id);

    /**
     * 根据名称获取标签
     * 
     * @param repositoryId 仓库ID
     * @param tagName 标签名称
     * @return 标签信息
     */
    @Select("SELECT t.*, u.real_name as creator_name, c.message as commit_message " +
            "FROM tag t " +
            "LEFT JOIN user u ON t.creator_id = u.id " +
            "LEFT JOIN commit c ON t.commit_id = c.id " +
            "WHERE t.repository_id = #{repositoryId} " +
            "AND t.tag_name = #{tagName} " +
            "AND t.deleted = 0")
    TagVO selectTagByName(@Param("repositoryId") String repositoryId,
                         @Param("tagName") String tagName);

    /**
     * 检查标签名称是否存在
     * 
     * @param repositoryId 仓库ID
     * @param tagName 标签名称
     * @param excludeId 排除的标签ID
     * @return 是否存在
     */
    @Select("SELECT COUNT(*) > 0 FROM tag " +
            "WHERE repository_id = #{repositoryId} " +
            "AND tag_name = #{tagName} " +
            "AND deleted = 0 " +
            "AND (#{excludeId} IS NULL OR id != #{excludeId})")
    Boolean checkTagNameExists(@Param("repositoryId") String repositoryId,
                              @Param("tagName") String tagName,
                              @Param("excludeId") String excludeId);

    /**
     * 获取版本标签列表
     * 
     * @param repositoryId 仓库ID
     * @param limit 限制数量
     * @return 版本标签列表
     */
    @Select("SELECT t.*, u.real_name as creator_name, c.message as commit_message " +
            "FROM tag t " +
            "LEFT JOIN user u ON t.creator_id = u.id " +
            "LEFT JOIN commit c ON t.commit_id = c.id " +
            "WHERE t.repository_id = #{repositoryId} " +
            "AND t.tag_type = 1 " +
            "AND t.deleted = 0 " +
            "ORDER BY t.version_order DESC, t.create_time DESC " +
            "LIMIT #{limit}")
    List<TagVO> selectVersionTags(@Param("repositoryId") String repositoryId,
                                 @Param("limit") Integer limit);

    /**
     * 获取发布标签列表
     * 
     * @param repositoryId 仓库ID
     * @param limit 限制数量
     * @return 发布标签列表
     */
    @Select("SELECT t.*, u.real_name as creator_name, c.message as commit_message " +
            "FROM tag t " +
            "LEFT JOIN user u ON t.creator_id = u.id " +
            "LEFT JOIN commit c ON t.commit_id = c.id " +
            "WHERE t.repository_id = #{repositoryId} " +
            "AND t.tag_type = 2 " +
            "AND t.deleted = 0 " +
            "ORDER BY t.create_time DESC " +
            "LIMIT #{limit}")
    List<TagVO> selectReleaseTags(@Param("repositoryId") String repositoryId,
                                 @Param("limit") Integer limit);

    /**
     * 获取最新版本标签
     * 
     * @param repositoryId 仓库ID
     * @return 最新版本标签
     */
    @Select("SELECT t.*, u.real_name as creator_name, c.message as commit_message " +
            "FROM tag t " +
            "LEFT JOIN user u ON t.creator_id = u.id " +
            "LEFT JOIN commit c ON t.commit_id = c.id " +
            "WHERE t.repository_id = #{repositoryId} " +
            "AND t.tag_type = 1 " +
            "AND t.deleted = 0 " +
            "ORDER BY t.version_order DESC, t.create_time DESC " +
            "LIMIT 1")
    TagVO selectLatestVersionTag(@Param("repositoryId") String repositoryId);

    /**
     * 获取提交的标签列表
     * 
     * @param commitId 提交ID
     * @return 标签列表
     */
    @Select("SELECT t.*, u.real_name as creator_name " +
            "FROM tag t " +
            "LEFT JOIN user u ON t.creator_id = u.id " +
            "WHERE t.commit_id = #{commitId} " +
            "AND t.deleted = 0 " +
            "ORDER BY t.create_time DESC")
    List<TagVO> selectCommitTags(@Param("commitId") String commitId);

    /**
     * 搜索标签
     * 
     * @param repositoryId 仓库ID
     * @param keyword 关键词
     * @param tagType 标签类型
     * @param limit 限制数量
     * @return 标签列表
     */
    @Select("SELECT t.*, u.real_name as creator_name, c.message as commit_message " +
            "FROM tag t " +
            "LEFT JOIN user u ON t.creator_id = u.id " +
            "LEFT JOIN commit c ON t.commit_id = c.id " +
            "WHERE t.repository_id = #{repositoryId} " +
            "AND (#{tagType} IS NULL OR t.tag_type = #{tagType}) " +
            "AND t.deleted = 0 " +
            "AND (t.tag_name LIKE CONCAT('%', #{keyword}, '%') " +
            "OR t.description LIKE CONCAT('%', #{keyword}, '%')) " +
            "ORDER BY t.create_time DESC " +
            "LIMIT #{limit}")
    List<TagVO> searchTags(@Param("repositoryId") String repositoryId,
                          @Param("keyword") String keyword,
                          @Param("tagType") Integer tagType,
                          @Param("limit") Integer limit);

    /**
     * 获取用户创建的标签
     * 
     * @param creatorId 创建者ID
     * @param repositoryId 仓库ID
     * @param limit 限制数量
     * @return 标签列表
     */
    @Select("SELECT t.*, u.real_name as creator_name, c.message as commit_message, r.name as repository_name " +
            "FROM tag t " +
            "LEFT JOIN user u ON t.creator_id = u.id " +
            "LEFT JOIN commit c ON t.commit_id = c.id " +
            "LEFT JOIN repository r ON t.repository_id = r.id " +
            "WHERE t.creator_id = #{creatorId} " +
            "AND (#{repositoryId} IS NULL OR t.repository_id = #{repositoryId}) " +
            "AND t.deleted = 0 " +
            "ORDER BY t.create_time DESC " +
            "LIMIT #{limit}")
    List<TagVO> selectUserTags(@Param("creatorId") String creatorId,
                              @Param("repositoryId") String repositoryId,
                              @Param("limit") Integer limit);

    /**
     * 比较两个标签之间的差异
     * 
     * @param repositoryId 仓库ID
     * @param fromTag 源标签
     * @param toTag 目标标签
     * @return 差异信息
     */
    Object compareTagDifferences(@Param("repositoryId") String repositoryId,
                                @Param("fromTag") String fromTag,
                                @Param("toTag") String toTag);

    /**
     * 获取标签之间的提交列表
     * 
     * @param repositoryId 仓库ID
     * @param fromTag 源标签
     * @param toTag 目标标签
     * @return 提交列表
     */
    List<Object> selectCommitsBetweenTags(@Param("repositoryId") String repositoryId,
                                         @Param("fromTag") String fromTag,
                                         @Param("toTag") String toTag);

    /**
     * 获取标签统计信息
     * 
     * @param repositoryId 仓库ID
     * @return 统计信息
     */
    @Select("SELECT " +
            "COUNT(*) as total_count, " +
            "COUNT(CASE WHEN tag_type = 1 THEN 1 END) as version_count, " +
            "COUNT(CASE WHEN tag_type = 2 THEN 1 END) as release_count, " +
            "COUNT(CASE WHEN tag_type = 3 THEN 1 END) as custom_count " +
            "FROM tag " +
            "WHERE repository_id = #{repositoryId} " +
            "AND deleted = 0")
    Object selectTagStatistics(@Param("repositoryId") String repositoryId);

    /**
     * 获取最大版本序号
     * 
     * @param repositoryId 仓库ID
     * @return 最大版本序号
     */
    @Select("SELECT COALESCE(MAX(version_order), 0) FROM tag " +
            "WHERE repository_id = #{repositoryId} " +
            "AND tag_type = 1 " +
            "AND deleted = 0")
    Integer getMaxVersionOrder(@Param("repositoryId") String repositoryId);

    /**
     * 批量删除标签
     * 
     * @param tagIds 标签ID列表
     * @return 影响行数
     */
    @Update("<script>" +
            "UPDATE tag SET deleted = 1, update_time = NOW() " +
            "WHERE id IN " +
            "<foreach collection='tagIds' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            "</script>")
    int batchDeleteTags(@Param("tagIds") List<String> tagIds);

    /**
     * 复制标签到其他提交
     * 
     * @param sourceTagId 源标签ID
     * @param targetCommitId 目标提交ID
     * @param newTagName 新标签名称
     * @param creatorId 创建者ID
     * @return 新标签ID
     */
    String copyTagToCommit(@Param("sourceTagId") String sourceTagId,
                          @Param("targetCommitId") String targetCommitId,
                          @Param("newTagName") String newTagName,
                          @Param("creatorId") String creatorId);
}
